package au.edu.qut.bpm.genbinder.genetic.evaluation.costmodels;

import java.util.List;
import java.util.Set;

import au.edu.qut.bpm.genbinder.GeneticBinder;
import au.edu.qut.bpm.genbinder.genetic.evaluation.LogEvaluator;
import au.edu.qut.bpm.genbinder.models.Activity;
import au.edu.qut.bpm.genbinder.models.ConcreteEventLog;

public class TighteningMultiObjectiveCostModel extends LogEvaluator {
	// This might be a neat idea: increase the punishment of hard constraint as
	// evolution runs, similar to sim. ann.

	private final static double TIMEUNIT = 1;
	private final static long HORIZON = 18;
	private final static long HORIZONSTART = 20;
	private final static CostCalculations costCalc = new CostCalculations();
	//private final static double COSTPERTIMEUNIT = 30;
	//private final static double COSTPERRESOURCE = 50;
	//private final static double COSTPERUTILIZATION = 10;
	//private final static long HORIZON = (long) (TIMEUNIT * 2);

	private static double nrTimesExecuted = 0;

	public double getFitness(ConcreteEventLog candidate, List<? extends ConcreteEventLog> population) {
		
		// TODO: Play around with this a bit more
		nrTimesExecuted++;
		double max = 1000;
		double w = nrTimesExecuted / (double) GeneticBinder.POPULATION_SIZE;
		if (w > max)
			w = max;

		double[] coefs = new double[] {
				30 + w / max * 1000,
				30 + w / max * 1000,
				30 + w / max * 1000,
				30 + w / max * 1000,
				1 };

		List<Set<Activity>> v = candidate.getLogViolatingActivities();
		return coefs[0] * (double) v.get(0).size()
				+ coefs[1] * (double) v.get(1).size()
				+ coefs[2] * (double) v.get(2).size()
				+ coefs[3] * (double) v.get(3).size()
				+ coefs[4] * getCost(candidate);
	}

	@Override
	public double getCost(ConcreteEventLog candidate) {
		return costCalc.calculateCost(candidate, TIMEUNIT, HORIZON, HORIZONSTART);
	}
}
